package com.pureut.production.service.impl;


import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pureut.common.core.exception.GlobalException;
import com.pureut.common.core.web.domain.AjaxResult;
import com.pureut.common.datascope.annotation.DataScope;
import com.pureut.common.security.utils.DictUtils;
import com.pureut.equipment.api.FeignEquipmentService;
import com.pureut.production.domain.ProcessCardTemplete;
import com.pureut.production.domain.ProcessProperty;
import com.pureut.production.domain.ProcessTempleteDrvice;
import com.pureut.production.domain.dto.ProcessCardTempleteDto;
import com.pureut.production.domain.dto.ProcessPropertyDto;
import com.pureut.production.domain.dto.ProcessTempleteDto;
import com.pureut.production.domain.dto.PublicProcessDto;
import com.pureut.production.domain.dto.equipment.GetDeviceInfoDto;
import com.pureut.production.domain.vo.ProcessCardTempleteVo;
import com.pureut.production.domain.vo.ProcessPropertyVo;
import com.pureut.production.domain.vo.ProcessTempleteVo;
import com.pureut.production.domain.vo.PublicProcessVo;
import com.pureut.production.mapper.ProcessCardTempleteMapper;
import com.pureut.production.mapper.ProcessPropertyMapper;
import com.pureut.production.mapper.ProcessTempleteDrviceMapper;
import com.pureut.production.service.ProcessCardTempleteService;
import com.pureut.production.service.ProcessPropertyService;
import com.pureut.production.service.ProcessTempleteDrviceService;
import com.pureut.system.api.domain.SysDictData;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 工艺卡模板实现层
 *
 * @author: CM
 * @date: 2023/2/16  16:45
 */
@Service
public class ProcessCardTempleteServiceImpl extends ServiceImpl<ProcessCardTempleteMapper, ProcessCardTemplete> implements ProcessCardTempleteService {

    /**
     * 工艺卡模板mapper
     */
    @Resource
    private ProcessCardTempleteMapper processCardTempleteMapper;

    /**
     * 工艺卡模板关联设备Service
     */
    @Resource
    private ProcessTempleteDrviceService processTempleteDrviceService;

    /**
     * 设备关联设备属性Service
     */
    @Resource
    private ProcessPropertyService processPropertyService;

    /**
     * 工艺卡模板关联设备Mapper
     */
    @Resource
    private ProcessTempleteDrviceMapper processTempleteDrviceMapper;

    /**
     * 设备关联设备属性Service
     */
    @Resource
    private ProcessPropertyMapper processPropertyMapper;

    /**
     * 设备模块模块feign
     */
    @Resource
    private FeignEquipmentService feignEquipmentService;


    /**
     *
     * {
     *     aa
     *     aa
     *     [
     *     {
     *         编码:'',
     *         设备名称:'',
     *         设备类型:'',
     *         列表:[
     *             {
     *                 表头:'',
     *                 值:'',
     *             },
     *             {}
     *         ],
     *
     *     }
     * ]}
     */


    /**
     * 工艺卡模板新增
     *
     * @param publicProcessVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean add(PublicProcessVo publicProcessVo) {
        //保存工艺卡模板
        ProcessCardTemplete processCardTemplete = new ProcessCardTemplete();
        //工艺卡阶别
        processCardTemplete.setTempleteName(publicProcessVo.getTempleteName());
        //生产阶别
        processCardTemplete.setProductionLevel(publicProcessVo.getProductionLevel());
        //生产线别
        processCardTemplete.setProductionLine(publicProcessVo.getProductionLine());

        //查询当前生产线别是否已经存在工艺卡模板
        List<ProcessCardTemplete> processCardTempleteList = processCardTempleteMapper.selectList(new QueryWrapper<ProcessCardTemplete>().lambda().eq(ProcessCardTemplete::getProductionLine, publicProcessVo.getProductionLine()));

        if (processCardTempleteList.size()>0){
            throw new GlobalException("同一线别只能添加一个工艺卡模板");
        }

        boolean save = save(processCardTemplete);

        //如果工艺卡模板新增成功,继续新增设备关联工艺卡模板，设备关联设备属性
        if (save) {
            //获取工艺卡模板id
            Long id = processCardTemplete.getId();

            List<ProcessCardTempleteVo> list = publicProcessVo.getList();

            for (ProcessCardTempleteVo processCardTempleteVo : list) {
                //保存工艺卡模板关联设备
                ProcessTempleteDrvice processTempleteDrvice = new ProcessTempleteDrvice();
                //添加设备编码
                processTempleteDrvice.setDrviceCode(processCardTempleteVo.getDeviceCode());
                //添加工艺卡模板id
                processTempleteDrvice.setProcessTempleteId(id);

                //保存工艺设备关联表
                processTempleteDrviceService.save(processTempleteDrvice);

                //设备属性集合
                List<ProcessPropertyVo> processList = processCardTempleteVo.getProcessList();
                List<ProcessProperty> processPropertyList = new ArrayList<>();
                for (ProcessPropertyVo processPropertyVo : processList) {
                    ProcessProperty processProperty = new ProcessProperty();
                    processProperty.setProperty(processPropertyVo.getDeviceAddedit());
                    processProperty.setValue(processPropertyVo.getValue());
                    processProperty.setTempleteDrviceId(processTempleteDrvice.getId());
                    processPropertyList.add(processProperty);
                }
                processPropertyService.saveBatch(processPropertyList);
            }

        }
        return save;
    }

    /**
     * 工艺卡模板列表
     *
     * @param processTempleteVo
     * @return
     */
    @Override
    @DataScope(deptAlias = "t1")
    public List<ProcessTempleteDto> selectTempleteList(ProcessTempleteVo processTempleteVo) {

        List<ProcessTempleteDto> list = processCardTempleteMapper.selectTemplete(processTempleteVo);

        List<SysDictData> statusArray = DictUtils.getDictCache("quality_production_level");
        Map<String, String> statusMap = statusArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        for (ProcessTempleteDto processTempleteDto : list) {
            processTempleteDto.setProductionLevelDict(statusMap.get(processTempleteDto.getProductionLevel()));
        }

        return list;
    }

    /**
     * 工艺卡模板查看
     *
     * @param id
     * @return
     */
    @Override
    public PublicProcessDto getView(Long id) {
        //通过id查出工艺模板
        ProcessCardTemplete processCardTemplete = processCardTempleteMapper.selectById(id);

        PublicProcessDto publicProcessDto = new PublicProcessDto();
        List<SysDictData> statusArray = DictUtils.getDictCache("quality_production_level");
        Map<String, String> statusMap = statusArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        publicProcessDto.setTempleteId(id);
        //生产阶别
        publicProcessDto.setProductionLevelDict(statusMap.get(processCardTemplete.getProductionLevel()));
        publicProcessDto.setProductionLevel(processCardTemplete.getProductionLevel());

        //模板名称
        publicProcessDto.setTempleteName(processCardTemplete.getTempleteName());
        //生产线别
        publicProcessDto.setProductionLine(processCardTemplete.getProductionLine());

        //获取设备+属性集合
        List<ProcessCardTempleteDto> list = new ArrayList<>();

        //获取设备编码到list集合中
        List<ProcessTempleteDrvice> processTempleteDrviceList = processTempleteDrviceMapper.selectList(new QueryWrapper<ProcessTempleteDrvice>().lambda().eq(ProcessTempleteDrvice::getProcessTempleteId, id));
        for (ProcessTempleteDrvice processTempleteDrvice : processTempleteDrviceList) {
            ProcessCardTempleteDto processCardTempleteDto = new ProcessCardTempleteDto();
            //添加设备编码
            processCardTempleteDto.setDeviceCode(processTempleteDrvice.getDrviceCode());

            AjaxResult deviceInfo = feignEquipmentService.getDeviceInfo(processTempleteDrvice.getDrviceCode());
            GetDeviceInfoDto getDeviceInfoDto = JSON.parseObject(JSON.toJSONString(deviceInfo.get("data")), GetDeviceInfoDto.class);
            processCardTempleteDto.setDeviceName(getDeviceInfoDto.getDeviceName());
            processCardTempleteDto.setDeviceType(getDeviceInfoDto.getDeviceType());

            //获取设备属性信息
            List<ProcessPropertyDto> processList = new ArrayList<>();

            //查询当前设备编码对应的属性和值
            List<ProcessProperty> processPropertyList = processPropertyMapper.selectList(new QueryWrapper<ProcessProperty>().lambda().eq(ProcessProperty::getTempleteDrviceId, processTempleteDrvice.getId()));
            for (ProcessProperty processProperty : processPropertyList) {
                ProcessPropertyDto processPropertyDto = new ProcessPropertyDto();
                processPropertyDto.setDeviceAddedit(processProperty.getProperty());
                processPropertyDto.setValue(processProperty.getValue());

                processList.add(processPropertyDto);
            }
            processCardTempleteDto.setProcessList(processList);
            list.add(processCardTempleteDto);

        }

        publicProcessDto.setList(list);

        return publicProcessDto;
    }

    /**
     * 工艺卡模板删除
     *
     * @param ids
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean remove(String ids) {
        //将ids根据逗号拆分成数组
        List<String> idStr = Arrays.asList(ids.split(","));

        List<Long> longList = new ArrayList<>();

        for (String id : idStr) {
            //工艺卡模板id
            Long templeteId = Long.parseLong(id);
            longList.add(templeteId);
            //获取工艺卡设备关联表
            List<ProcessTempleteDrvice> processTempleteDrviceList = processTempleteDrviceMapper.selectList(new QueryWrapper<ProcessTempleteDrvice>().lambda().eq(ProcessTempleteDrvice::getProcessTempleteId, templeteId));
            if (processTempleteDrviceList.size() > 0) {
                //设备
                for (ProcessTempleteDrvice processTempleteDrvice : processTempleteDrviceList) {

                    List<ProcessProperty> processPropertyList = processPropertyMapper.selectList(new QueryWrapper<ProcessProperty>().lambda().eq(ProcessProperty::getTempleteDrviceId, processTempleteDrvice.getId()));

                    //删除设备属性表
                    processPropertyMapper.deleteBatchIds(processPropertyList);
                }
                //删除设备工艺表
                processTempleteDrviceMapper.deleteBatchIds(processTempleteDrviceList);
            }
        }
        return processCardTempleteMapper.deleteBatchIds(longList) > 0;
    }

    /**
     * 工艺卡模板修改
     *
     * @param publicProcessVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean edit(PublicProcessVo publicProcessVo) {
        //删除工艺卡模板
        boolean remove = remove(String.valueOf(publicProcessVo.getId()));
        //新增工艺卡模板
        if (remove) {
            add(publicProcessVo);
        }
        return remove;
    }

    /**
     * 根据线别查询工艺卡模板
     *
     * @param line
     * @return
     */
    @Override
    public PublicProcessDto getLine(String line) {
        //通过id查出工艺模板
        ProcessCardTemplete processCardTemplete = processCardTempleteMapper.selectOne(new QueryWrapper<ProcessCardTemplete>().lambda().eq(ProcessCardTemplete::getProductionLine, line));

        if (processCardTemplete == null) {
            throw new GlobalException("该线别对应工艺卡模板不存在");
        }

        PublicProcessDto publicProcessDto = new PublicProcessDto();
        publicProcessDto.setTempleteId(processCardTemplete.getId());
        List<SysDictData> statusArray = DictUtils.getDictCache("quality_production_level");
        Map<String, String> statusMap = statusArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        //生产阶别
        publicProcessDto.setProductionLevel(statusMap.get(processCardTemplete.getProductionLevel()));
        //模板名称
        publicProcessDto.setTempleteName(processCardTemplete.getTempleteName());
        //生产线别
        publicProcessDto.setProductionLine(processCardTemplete.getProductionLine());
        //工艺卡id
        publicProcessDto.setProcessCardId(processCardTemplete.getId());
        //获取设备+属性集合
        List<ProcessCardTempleteDto> list = new ArrayList<>();

        //获取设备编码到list集合中
        List<ProcessTempleteDrvice> processTempleteDrviceList = processTempleteDrviceMapper.selectList(new QueryWrapper<ProcessTempleteDrvice>().lambda().eq(ProcessTempleteDrvice::getProcessTempleteId, processCardTemplete.getId()));
        for (ProcessTempleteDrvice processTempleteDrvice : processTempleteDrviceList) {
            ProcessCardTempleteDto processCardTempleteDto = new ProcessCardTempleteDto();
            //添加设备编码
            processCardTempleteDto.setDeviceCode(processTempleteDrvice.getDrviceCode());

            AjaxResult deviceInfo = feignEquipmentService.getDeviceInfo(processTempleteDrvice.getDrviceCode());
            GetDeviceInfoDto getDeviceInfoDto = JSON.parseObject(JSON.toJSONString(deviceInfo.get("data")), GetDeviceInfoDto.class);
            processCardTempleteDto.setDeviceName(getDeviceInfoDto.getDeviceName());
            processCardTempleteDto.setDeviceType(getDeviceInfoDto.getDeviceType());


            //获取设备属性信息
            List<ProcessPropertyDto> processList = new ArrayList<>();

            //查询当前设备编码对应的属性和值
            List<ProcessProperty> processPropertyList = processPropertyMapper.selectList(new QueryWrapper<ProcessProperty>().lambda().eq(ProcessProperty::getTempleteDrviceId, processTempleteDrvice.getId()));
            for (ProcessProperty processProperty : processPropertyList) {
                ProcessPropertyDto processPropertyDto = new ProcessPropertyDto();
                processPropertyDto.setDeviceAddedit(processProperty.getProperty());
                processPropertyDto.setValue(processProperty.getValue());

                processList.add(processPropertyDto);
            }
            processCardTempleteDto.setProcessList(processList);
            list.add(processCardTempleteDto);
        }
        publicProcessDto.setList(list);
        return publicProcessDto;
    }

}
